// $Id: util.c,v 1.1.1.1 2012/02/17 03:45:26 hzheng Exp $

#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "base64.h"

#include "log.h"

#include "util.h"

int evcpe_is_ipaddr(const char *address)
{
	int i;

	for (i = 0; i < strlen(address); i++) {
		if (address[i] != '.' && (address[i] < '0' || address[i] > '9'))
			return 0;
	}
	return 1;
}

int evcpe_is_num(const char *str)
{
	int i;

	for (i = 0; i < strlen(str); i++) {
		if (str[i] < '0' || str[i] > '9')
			return 0;
	}
	return 1;
}

int evcpe_add_buffer(struct evbuffer *buffer, const char *fmt, ...)
{
	int rc;
	va_list ap;

	va_start(ap, fmt);
	if (evbuffer_add_vprintf(buffer, fmt, ap) < 0)
		rc = ENOMEM;
	else
		rc = 0;
	va_end(ap);

	return rc;
}

int evcpe_encode_base64(struct evbuffer *buffer, u_char *data, unsigned len)
{
	int rc;
	//char *out_data_start = NULL;
	unsigned out_len = 0;

	/*out_data_start = */base64_encode(data, len, (size_t *)&out_len, 0);

	if(evbuffer_add(buffer, data, len) < 0)
		rc = ENOMEM;
	else
		rc = 0;
	return rc;
}

int evcpe_decode_base64(struct evbuffer *buffer, unsigned *len, 
		u_char **data_start, unsigned * out_len)
{
	if(*len > EVBUFFER_LENGTH(buffer))
		return ENOMEM;
	else 
		*data_start = base64_decode(EVBUFFER_DATA(buffer), (size_t )*len, (size_t *) out_len);
	
	evbuffer_drain(buffer, *len);
	
	return 0;
}

int evcpe_strcmp(const char *a, unsigned alen, const char *b, unsigned blen)
{
	int result;
	unsigned len;

	len = alen > blen ? blen : alen;
	result = strncmp(a, b, len);

	if (alen != blen && result == 0) {
		if (alen > blen)
			result = 1;
		else
			result = -1;
	}

	return result;
}

int evcpe_strncmp(const char *a, const char *b, unsigned blen)
{
	return evcpe_strcmp(a, strlen(a), b, blen);
}
int evcpe_bool2int(const char *text, unsigned len)
{
	if (len == 0) return -1;
	if(!strncasecmp(text,"true",strlen("true"))){
		return 1;
	}
	else if(!strncasecmp(text,"false",strlen("false"))){
		return 0;
	}
	return -1;
}
int evcpe_atol(const char *text, unsigned len, long *value)
{
	int i, negative;

	if (len == 0) return EINVAL;
	
	if(!strncasecmp(text,"true",strlen("true"))){
		*value = 1;
		return 0;
	}
	else if(!strncasecmp(text,"false",strlen("false"))){
		*value = 0;
		return 0;
	}
	
	if (text[0] == '-') {
		if (len == 1)
			return EINVAL;
		i = 1;
		negative = 1;
	} else {
		i = 0;
		negative = 0;
	}
	*value = 0;
	while (i < len) {
		if (text[i] < '0' || text[i] > '9') return EINVAL;
		if (negative)
			*value -= (text[i] - '0');
		else
			*value += (text[i] - '0');
		i ++;
		if (i != len)
			*value *= 10;
	}
	return 0;
}

int evcpe_atou(const char *text, unsigned len, unsigned int *value)
{
	int i, negative;

	if (len == 0) return EINVAL;

	if(!strncasecmp(text,"true",strlen("true"))){
		*value = 1;
		return 0;
	}
	else if(!strncasecmp(text,"false",strlen("false"))){
		*value = 0;
		return 0;
	}

	if (text[0] == '-') {
		if (len == 1)
			return EINVAL;
		i = 1;
		negative = 1;
	} else {
		i = 0;
		negative = 0;
	}
	*value = 0;
	while (i < len) {
		if (text[i] < '0' || text[i] > '9') return EINVAL;
		if (negative)
			*value -= (text[i] - '0');
		else
			*value += (text[i] - '0');
		i ++;
		if (i != len)
			*value *= 10;
	}
	return 0;
}

char *evcpe_ltoa(long value)
{
	char buffer[32];
	snprintf(buffer, sizeof(buffer), "%ld", value);
	return strdup(buffer);
}

int evcpe_strdup(const char *string, unsigned len, char **ptr)
{
	if (!(*ptr = malloc(len + 1))) {
		evcpe_error(__func__, "failed to malloc: %d", len + 1);
		return ENOMEM;
	}
	memcpy(*ptr, string, len);
	(*ptr)[len] = '\0';
	return 0;
}
